
package org.sopt.dev.ImgKnight.agent.Config;

import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.PushbackInputStream;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

public class AgentConfig {

	public String AgentName = null;
	
	public boolean UsedAgentExclusion = true;
	
	public String AgentCacheEngineType = null;
	
	public int AgentCacheSize = -1;
	
	public int ControllerPort = -1;
	
	public int BufferedFetchSize = -1;
	
	public int FetchBufferSize = -1;
	
	public int FileDownloadBufferSize = -1;
	
	public String URLFrontierServIp = null;
	
	public int URLFrontierServPort = -1;
	
	public int HttpGetTimeout = -1;
	
	public int HttpGetSoTimeout = -1;
	
	public int HttpHeadTimeout = -1;
	
	public int HttpHeadSoTimeout = -1;
	
	public int TakeUrlParallelDegree = -1;
	
	public int TakeResourceParallelDegree = -1;
	
	public boolean UsedSeenImageFilter = false;
	
	public int SeenImageFilterHighWaterMark = -1;
	
	public String[] AllowResourceType = null;
	
	public int ResourceMinimumByte = -1;
	
	public String DownloadBaseDir = null;
	
	private Logger serviceLogger = null;
	
	public AgentConfig() {
		serviceLogger = Logger.getLogger("agent.service");
	}
	
	public boolean BuildConfig(File file) throws IOException, FileNotFoundException {
		if( !isValidFilePath(file) )
			throw new FileNotFoundException("Could not open/read file: " + file.getAbsolutePath());
		
		FileInputStream 	fs = new FileInputStream(file);
		BufferedInputStream bs = new BufferedInputStream(fs);
		PushbackInputStream ps = new PushbackInputStream(bs);
		
		while( readLine(ps) ) {
			if( key != null && value != null ) {
				if( key.equalsIgnoreCase("AgentName") ) {
					AgentName = value;
					serviceLogger.debug("AgentName: " + AgentName);
				}
				else if( key.equalsIgnoreCase("AgentCacheEngineType") ) {
					AgentCacheEngineType = value;
					serviceLogger.debug("AgentCacheEngineType: " + AgentCacheEngineType);
				}
				else if( key.equalsIgnoreCase("UsedAgentExclusion") ) {
					if( value.equalsIgnoreCase("true") )
						UsedAgentExclusion = true;
					else
						UsedAgentExclusion = false;
					serviceLogger.debug("UsedAgentExclusion: " + UsedAgentExclusion);
				}
				else if( key.equalsIgnoreCase("AgentCacheSize") ) {
					AgentCacheSize = Integer.parseInt(value);
					serviceLogger.debug("AgentCacheSize: " + AgentCacheSize);
				}
				else if( key.equalsIgnoreCase("ControllerPort") ) {
					ControllerPort = Integer.parseInt(value);
					serviceLogger.debug("ControllerPort: " + ControllerPort);
				}
				else if( key.equalsIgnoreCase("BufferedFetchSize") ) {
					BufferedFetchSize = Integer.parseInt(value);
					serviceLogger.debug("BufferedFetchSize: " + BufferedFetchSize);
				}
				else if( key.equalsIgnoreCase("FetchBufferSize") ) {
					FetchBufferSize = Integer.parseInt(value);
					serviceLogger.debug("FetchBufferSize: " + FetchBufferSize);
				}
				else if( key.equalsIgnoreCase("FileDownloadBufferSize") ) {
					FileDownloadBufferSize = Integer.parseInt(value);
					serviceLogger.debug("FileDownloadBufferSize: " + FileDownloadBufferSize);
				}
				else if( key.equalsIgnoreCase("URLFrontierServIp") ) {
					URLFrontierServIp = value;
					serviceLogger.debug("URLFrontierServIp: " + URLFrontierServIp);
				}
				else if( key.equalsIgnoreCase("URLFrontierServPort") ) {
					URLFrontierServPort = Integer.parseInt(value);
					serviceLogger.debug("URLFrontierServPort: " + URLFrontierServPort);
				}
				else if( key.equalsIgnoreCase("HttpGetTimeout") ) {
					HttpGetTimeout = Integer.parseInt(value);
					serviceLogger.debug("HttpGetTimeout: " + HttpGetTimeout);
				}
				else if( key.equalsIgnoreCase("HttpGetSoTimeout") ) {
					HttpGetSoTimeout = Integer.parseInt(value);
					serviceLogger.debug("HttpGetSoTimeout: " + HttpGetSoTimeout);
				}
				else if( key.equalsIgnoreCase("HttpHeadTimeout") ) {
					HttpHeadTimeout = Integer.parseInt(value);
					serviceLogger.debug("HttpHeadTimeout: " + HttpHeadTimeout);
				}
				else if( key.equalsIgnoreCase("HttpHeadSoTimeout") ) {
					HttpHeadSoTimeout = Integer.parseInt(value);
					serviceLogger.debug("HttpHeadSoTimeout: " + HttpHeadSoTimeout);
				}
				else if( key.equalsIgnoreCase("TakeUrlParallelDegree") ) {
					TakeUrlParallelDegree = Integer.parseInt(value);
					serviceLogger.debug("TakeUrlParallelDegree: " + TakeUrlParallelDegree);
				}
				else if( key.equalsIgnoreCase("TakeResourceParallelDegree") ) {
					TakeResourceParallelDegree = Integer.parseInt(value);
					serviceLogger.debug("TakeImageParallelDegree: " + TakeResourceParallelDegree);
				}
				else if( key.equalsIgnoreCase("UsedSeenImageFilter") ) {
					if( value.equalsIgnoreCase("true") )
						UsedSeenImageFilter = true;
					else
						UsedSeenImageFilter = false;
					serviceLogger.debug("UsedSeenImageFilter: " + UsedSeenImageFilter);
				}
				else if( key.equalsIgnoreCase("SeenImageFilterHighWaterMark") ) {
					SeenImageFilterHighWaterMark = Integer.parseInt(value);
					serviceLogger.debug("SeenImageFilterHighWaterMark: " + SeenImageFilterHighWaterMark);
				}
				else if( key.equalsIgnoreCase("AllowResourceType") ) {
					StringTokenizer tokenizer = new StringTokenizer(value);
					AllowResourceType = new String[tokenizer.countTokens()];
					int count = 0;
					while( tokenizer.hasMoreTokens() ) {
						AllowResourceType[count++] = tokenizer.nextToken();
						serviceLogger.debug("AllowResourceType: " + AllowResourceType[count-1]);
					}
				}
				else if( key.equalsIgnoreCase("ResourceMinimumByte") ) {
					ResourceMinimumByte = Integer.parseInt(value);
					serviceLogger.debug("ResourceMinimumByte: " + ResourceMinimumByte);
				}
				else if( key.equalsIgnoreCase("DownloadBaseDir") ) {
					DownloadBaseDir = value;
					serviceLogger.debug("DownloadBaseDir: " + DownloadBaseDir);
				}
			}
		}
		ps.close();
		return true;
	}
	
	boolean isValidFilePath(File file) {
		return (file.isFile() && file.canRead());
	}
	
	static final int MAX_LINE_LENGTH = 1024;
	String key, value;
	StringBuffer linebuf = new StringBuffer();
	boolean readLine(PushbackInputStream in) throws IOException {
		key 	= null;
		value 	= null;
		linebuf.setLength(0);
		
		int c;
		int n = 0;
		boolean saw_eoln = false;
		while( true ) {
			c = in.read();
			if( c == -1 )
				break;
			else if( c == '\r' || c == '\n' )
				saw_eoln = true;
			else if( saw_eoln ) {
				in.unread(c);
				break;
			}
			else {
				linebuf.append((char)c);
			}
			++n;
			if( n == MAX_LINE_LENGTH )
				break;
		}
		if( n == 0 )
			return false;

		String line = linebuf.toString();
		line.trim();
		if( line.startsWith("#") )
			return true;
		int colon = line.indexOf (':');
		if( colon == -1 ) {
			key 	= null;
			value 	= null;
		}
		else {
			key  = line.substring(0, colon).trim();
			value = line.substring(colon+1).trim();
		}		 
		return true;
	}
}
